<?php
// +----------------------------------------------------------------------
// | ZGUAN [ 致力于帮助更多的中小企业物联网转型 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.zguan.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ZGUAN 并不是自由软件，未经许可不能去掉ZGUAN 相关版权
// +----------------------------------------------------------------------
// | Author: ZGUAN Team <admin@zguan.cn>  0769-82282996  15899929162
// +----------------------------------------------------------------------
namespace app\common\repositories\property\basic;

use think\facade\Db;
use think\exception\ValidateException;
use app\common\repositories\BaseRepository;
use app\common\dao\property\basic\PropertyBasicDao;
use app\common\repositories\room\RoomBasicRepository;
use app\common\repositories\property\users\PropertyUsersLogRepository;
use app\common\repositories\system\upload\SystemUploadFileRepository;
use app\common\repositories\property\auth\PropertyAuthAccessRepository;

/**
 * Class PropertyBasicRepository
 *
 * @mixin PropertyBasicDao
 */
class PropertyBasicRepository extends BaseRepository
{

    public function __construct(PropertyBasicDao $dao)
    {
        $this->dao = $dao;
    }


    public function getPropertyList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->with([
                'cateInfo' => function ($query) {
                    $query->bind(['cate_name' => 'name']);
                },
                'fileInfo' => function ($query) {
                    $query->bind(['picture' => 'show_src']);
                },
            ])
            ->field('id,name,add_time,address,cover_area,building_area,is_show,cate_id,picture_id')
            ->append(['room_all', 'today_check_in', 'today_refund', 'room_empty_all', 'room_vacancy_rate'])
            ->order('id', 'desc')
            ->select();
        return compact('count', 'list');
    }

    /**
     * 获取管理权限列表
     * @param array $where
     * @param $page
     * @param $limit
     * @param int|null $propertyId
     * @return array
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-11 21:10
     */
    public function getApiAllPropertyList(array $where, $page, $limit, int $propertyId = null)
    {
        /** @var PropertyAuthAccessRepository $propertyAuthAccessRepository */
        $propertyAuthAccessRepository = app()->make(PropertyAuthAccessRepository::class);
        $propertyIds = $propertyAuthAccessRepository->getPropertyIdsByUserId($where['add_uid']);
        $query = $this->dao->search($where, $propertyId)
            ->where(function ($query) use ($where, $propertyIds) {
                ## 用户授权物业或用户自己添加电表
                $query->where('id', 'in', $propertyIds);
                $query->whereOr('add_uid', $where['add_uid']);
            });
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->with([
                'fileInfo' => function ($query) {
                    $query->bind(['picture' => 'show_src']);
                }
            ])
            ->field('id,name,picture_id')
            ->order('id', 'desc')
            ->select();
        return compact('count', 'list');
    }

    /**
     * 获取全部物业列表
     * @param array $where
     * @param $page
     * @param $limit
     * @param int|null $propertyId
     * @return array
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-11 21:10
     */
    public function getApiList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->with([
                'cateInfo' => function ($query) {
                    $query->bind(['cate_name' => 'name']);
                },
                'fileInfo' => function ($query) {
                    $query->bind(['picture' => 'show_src']);
                }
            ])
            ->append(['label_list', 'room_empty_all'])
            ->field('id,name,cover_area,building_area,picture_id')
            ->order('id', 'desc')
            ->orderRaw('rand()')
            ->select();
        return compact('count', 'list');
    }


    public function addInfo(array $data, int $propertyId = 1, int $userId = 0)
    {
        if (!isset($data['code']) || !$data['code']) {
            $data['code'] = $this->getCoce(5);
        }
        /** @var SystemUploadFileRepository $uploadFileRepository */
        $uploadFileRepository = app()->make(SystemUploadFileRepository::class);
        $fileInfo = $uploadFileRepository->getFileData($data['picture']);
        if ($fileInfo) {
            $data['picture_id'] = $fileInfo['id'];
        }
        unset($data['picture']);

        return Db::transaction(function () use ($data, $propertyId, $userId) {
            $labelIds = $data['label_id'];
            unset($data['label_id']);
            $data['property_id'] = $propertyId;
            $res = $this->dao->create($data);

            if ($labelIds) {
                /** @var PropertyBasicLabelRepository $propertyBasicLabelRepository */
                $propertyBasicLabelRepository = app()->make(PropertyBasicLabelRepository::class);
                $insertData = [];
                foreach ($labelIds as $v) {
                    $insertData[] = [
                        'label_id' => $v,
                        'property_id' => $res['id'],
                        'property_id' => $res['property_id'],
                    ];
                }
                $propertyBasicLabelRepository->insertAll($insertData);
            }
            ##  添加主管理员
            /** @var PropertyAuthAccessRepository $propertyAuthAccessRepository */
            $propertyAuthAccessRepository = app()->make(PropertyAuthAccessRepository::class);
            $authData['is_owner'] = 1;
            $authData['user_id'] = $res['add_uid'];
            $authData['property_id'] = $res['id'];
            $propertyAuthAccessRepository->create($authData);

            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($propertyId, $userId, 'PROPERTY.BASIC.ADD', $data);

            event('property.create', [
                'userId' => $userId,
                'propertyInfo' => $res,
            ]);
            return $res;
        });
    }

    public function editInfo($info, array $data, int $userId = 0)
    {
        if ($data['picture']) {
            /** @var SystemUploadFileRepository $uploadFileRepository */
            $uploadFileRepository = app()->make(SystemUploadFileRepository::class);
            $fileInfo = $uploadFileRepository->getFileData($data['picture']);
            if ($fileInfo) {
                if ($fileInfo['id'] != $info['picture_id']) {
                    $data['picture_id'] = $fileInfo['id'];
                }
            }
        }
        unset($data['picture']);
        return Db::transaction(function () use ($data, $info, $userId) {
            $labelIds = $data['label_id'];
            unset($data['label_id']);

            /** @var PropertyBasicLabelRepository $propertyBasicLabelRepository */
            $propertyBasicLabelRepository = app()->make(PropertyBasicLabelRepository::class);
            $propertyBasicLabelRepository->deleteByPropertyId($info['id']);
            if ($labelIds) {
                $insertData = [];
                foreach ($labelIds as $v) {
                    $insertData[] = [
                        'label_id' => $v,
                        'property_id' => $info['id'],
                        'property_id' => $info['property_id'],
                    ];
                }
                $resC = $propertyBasicLabelRepository->insertAll($insertData);
            }

            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($info['property_id'], $userId, 'PROPERTY.BASIC.EDIT', $data);
            $res = $this->dao->update($info['id'], $data);
            event('property.redact', [
                'userId' => $userId,
                'propertyInfo' => $info,
            ]);
            return ($res || $resC);
        });
    }


    public function getDetail(int $id)
    {
        $data = $this->dao->search([])
            ->where('id', $id)
            ->with([
                'fileInfo' => function ($query) {
                    $query->bind(['picture' => 'show_src']);
                }
            ])
            ->hidden(['file'])
            ->find();
        return $data;
    }


    public function getApiDetail(int $id)
    {
        $data = $this->dao->search([])
            ->where('id', $id)
            ->with([
                'fileInfo' => function ($query) {
                    $query->bind(['picture' => 'show_src']);
                },
                'cateInfo' => function ($query) {
                    $query->bind(['cate_name' => 'name']);
                }
            ])
            ->append(['label_list'])
            ->field('id,name,picture_id,firm_id,code,cate_id,cover_area,building_area,longitude,latitude,address,remark')
            ->hidden(['fileInfo', 'cateInfo', 'picture_id'])
            ->find();
        return $data;
    }


    /**
     *  根据物业 ID 查楖况
     * @param int $id
     * @return array|mixed|\think\db\BaseQuery|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 17:47
     */
    public function getPropertySurvey(int $id)
    {
        $data = $this->dao->search([])
            ->where('id', $id)
            ->append(['room_all', 'room_empty_all', 'today_check_in', 'today_refund', 'all_check_in', 'room_vacancy_rate'])
            ->field('id')
            ->find();
        return $data;
    }


    public function batchDelete(array $ids, int $userId = 0)
    {
        $list = $this->dao->selectWhere([
            ['id', 'in', $ids]
        ]);
        if ($list) {
            foreach ($list as $k => $v) {
                $this->deleteInfo($v, $userId);
            }
            return $list;
        }
        return [];
    }

    public function deleteInfo($info, int $userId = 0)
    {
        return Db::transaction(function () use ($info, $userId) {
            $res = $this->dao->delete($info['id']);

            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($info['property_id'], $userId, 'PROPERTY.BASIC.DEL', $info);

            event('property.delete', [
                'userId' => $userId,
                'propertyInfo' => $info,
            ]);
            return $res;
        });
    }

    /**
     *  根据物业 ID 检测出租中的房间
     * @param int $id
     * @return true
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-13 15:24
     */

    public function deleteCheckRoom(int $propertyId)
    {
        /** @var RoomBasicRepository $roomBasicRepository */
        $roomBasicRepository = app()->make(RoomBasicRepository::class);
        $rentRoomNum = $roomBasicRepository->getSearch(['property_id' => $propertyId])
            ->where('status', 2)
            ->count();
        if ($rentRoomNum > 0) {
            throw new ValidateException('存在已出租的房间，请先处理');
        }
        return true;
    }

    /**
     * 验证管理权限
     * @param int $id
     * @param $userId
     * @return bool
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-12 21:52
     */
    public function existsByUserId(int $id, $userId)
    {
        return $this->dao->search([])
                ->where(function ($query) use ($userId) {
                    /** @var PropertyAuthAccessRepository $propertyAuthAccessRepository */
                    $propertyAuthAccessRepository = app()->make(PropertyAuthAccessRepository::class);
                    $propertyIds = $propertyAuthAccessRepository->getPropertyIdsByUserId($userId);
                    ## 用户授权物业或用户自己添加电表
                    $query->where('id', 'in', $propertyIds);
                    $query->whereOr('add_uid', $userId);
                })->where('id', $id)->count() > 0;
    }

    public function getCoce($num = 5)
    {
        $code = get_property_code(5);
        if ($code) {
            $codeCount = $this->dao->getSearch(['code' => $code])->count();
            if ($codeCount <= 0) {
                return $code;
            }
            return $this->getCoce($num);
        }
    }

    /**
     *  根据物业编码查询物业信息
     * @param $code
     * @return \app\common\model\BaseModel|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-27 09:04
     */
    public function getByKeyCode($code)
    {
        $query = $this->dao->getSearch([
            'code' => $code
        ]);
        $list = $query->find();
        return $list;
    }
}